#pragma once

#include "bdc_motor.h"
#include "pid_ctrl.h"
#include "encoder.h"

#ifdef __cplusplus
exturn "C" {
#endif // __cplusplus

typedef struct {
    bdc_motor_config_t motor_config;
    bdc_motor_mcpwm_config_t mcpwm_config;
    encoder_config_t encoder_config;
    pid_ctrl_config_t pid_config;
} mc_config_t;

#define MC_CONFIG_DEFAULT(p, i, d) {                \
    .motor_config = {                               \
        .pwm_freq_hz = 25000,                       \
    },                                              \
    .mcpwm_config = {                               \
        .group_id = 0,                              \
        .resolution_hz = 10000000,                  \
    },                                              \
    .pid_config = {                                 \
        .init_param = {                             \
            .kp = p,                                \
            .ki = i,                                \
            .kd = d,                                \
            .cal_type = PID_CAL_TYPE_INCREMENTAL,   \
            .max_output = 10000000. / 25000 - 2,    \
            .min_output = -(10000000. / 25000 - 2), \
            .max_integral = 1000,                   \
            .min_integral = -1000,                  \
        }                                           \
    },                                              \
}

struct mc_t;
typedef struct mc_t *mc_handle_t;

esp_err_t mc_timer_loop_create(TickType_t pid_period_tick, TickType_t encoder_period_tick);
esp_err_t mc_timer_loop_del(void);
esp_err_t mc_timer_loop_start(void);
esp_err_t mc_timer_loop_stop(void);
esp_err_t mc_new(const mc_config_t *config, float max_rpm, mc_handle_t *handle);
esp_err_t mc_del(mc_handle_t handle);
esp_err_t mc_add_to_timer_loop(mc_handle_t handle);
esp_err_t mc_remove_from_timer_loop(mc_handle_t handle);
void mc_set_pid_params(mc_handle_t handle, float kp, float ki, float kd);
void mc_set_expect_rpm(mc_handle_t handle, float expect_rpm);
float mc_get_real_rpm(mc_handle_t handle);

#ifdef __cplusplus
}
#endif // __cplusplus
